package fr.umlv.escapeir.ship;

import java.awt.Image;
import java.awt.geom.Point2D;

import org.jbox2d.collision.AABB;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.MathUtils;
import org.jbox2d.common.Vec2;

import fr.umlv.escapeir.GameWorld;
import fr.umlv.escapeir.game.LinearMove;
import fr.umlv.escapeir.game.WorldActor;
import fr.umlv.escapeir.gesture.Gesture;
import fr.umlv.escapeir.gesture.GestureListener;
import fr.umlv.escapeir.weapon.Weapon;
import fr.umlv.escapeir.weapon.WeaponFactory;

public class HeroShip extends PolygonShip implements GestureListener {

	public static final int GROUP_INDEX = -1;
	private static final float ANGLE = 0;
	private static final int WEAPON_GESTURE_TOLERANCE = 20;

	private HeroShip(GameWorld gameWorld, PolygonShape shape, Image image,
			Vec2 imageTopLeft, Vec2 imageBottomRight) {

		super(gameWorld, gameWorld.startingPoint().x,
				gameWorld.startingPoint().y, ANGLE,
				shape, image, imageTopLeft, imageBottomRight, GROUP_INDEX);
	}

	static HeroShip createInWorld(GameWorld world,
			PolygonShape shape, Image image,
			Vec2 imageTopLeft, Vec2 imageBottomRight) {
		HeroShip act = new  HeroShip(world, shape, image, imageTopLeft, imageBottomRight);
		act.setBody(world.addActor(act, act.getBdef()));
		act.getBody().createFixture(act.getFdef());
		act.getBody().m_userData = act;
		return act;
	}

	@Override
	public void gestureReceived(Gesture g) {
		switch (g.type()) {
		case LINE:
			lineGesture(g);
			break;
		case POINT:
			pointGesture(g);
		default:
			break;
		}
	}

	private void lineGesture (Gesture g) {
		//Check if the gesture line append on the weapon
		Point2D clickDownPoint = g.getOrigin();
		AABB box = getWorld().worldBoxFromScreen(new Vec2((float)clickDownPoint.getX(),
				(float)clickDownPoint.getY()), WEAPON_GESTURE_TOLERANCE);

		AABB center = new AABB(getWeapon().position(), getWeapon().position());

		//fire the weapon
		if (center.contains(box)) {
			Point2D clickUpPoint = g.getEnd();
			Vec2 clickOrigin = getWorld().worldCoordinateFromScreen((float)clickDownPoint.getX(),
					(float)clickDownPoint.getY());
			Vec2 clickDest = getWorld().worldCoordinateFromScreen((float)clickUpPoint.getX(),
					(float)clickUpPoint.getY());
			
			float theta = MathUtils.fastAtan2(clickDest.y-clickOrigin.y,
					clickDest.x-clickOrigin.x);
			
			
			fire(theta);
			return;
		}
		//apply linear move to the ship
		setBehavior(new LinearMove(getBody(), g.getDirection(), g.value(), 1));
	}

	private void pointGesture (Gesture g) {
		//Check if the click  append on the ship
		Point2D clickDownPoint = g.getOrigin();
		AABB box = getWorld().worldBoxFromScreen(new Vec2((float)clickDownPoint.getX(),
				(float)clickDownPoint.getY()), WEAPON_GESTURE_TOLERANCE);

		AABB center = new AABB(position(), position());

		//fire the weapon
		if (center.contains(box)) {
			WeaponFactory.create(this);
			return;
		}
		//apply linear move to the ship
		setBehavior(new LinearMove(getBody(), g.getDirection(), g.value(), 1));
	}

	@Override
	public Type type() {
		return WorldActor.Type.HERO;
	}

	@Override
	public void touch(WorldActor actor) {
		System.out.println(getBody().getPosition());
	}

	@Override
	public void addWeapon(Weapon weapon) {
		setWeapon(weapon);
	}
}


